package test;

import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacpp.Loader;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameGrabber;
import org.bytedeco.javacv.FrameRecorder;
import org.bytedeco.javacv.OpenCVFrameConverter;
import org.bytedeco.opencv.global.opencv_imgcodecs;
import org.bytedeco.opencv.global.opencv_objdetect;
import org.bytedeco.opencv.opencv_core.IplImage;


public class RecordPush {
    final static int rate = 1000000;
    final static int audioRate = 100000;
    final static int fps = 30;
    final static int width = 1920;
    final static int height = 1080;
    public static void main(String[] args)
            throws Exception {
        String inputFile = "rtsp://admin:123456789a@192.168.31.66:554/h264/ch1/main/av_stream";
        String outputFile = "rtmp://42.193.125.79:1935/live/index";//本地配置的推流地址
        recordPush(inputFile, outputFile, fps);
    }

    public static void recordPush(String inputFile,String outputFile,int v_rs) throws Exception, org.bytedeco.javacv.FrameRecorder.Exception, InterruptedException{

        Loader.load(opencv_objdetect.class);
        long startTime=0;

        FrameGrabber grabber =FFmpegFrameGrabber.createDefault(inputFile);
        System.out.println("开始获取FrameGrabber grabber："+grabber);
        try {
            System.out.println("获取 grabber的start："+grabber);
            grabber.setImageHeight(height);
            grabber.setImageWidth(width);
            grabber.setOption("rtsp_transport", "tcp"); // 使用tcp的方式，不然会丢包很严重
            grabber.start();
        } catch (Exception e) {
            try {
                System.out.println("获取 grabber的restart："+grabber);
                grabber.restart();
            } catch (Exception e1) {
                System.out.println("出错了："+grabber);
                throw e;
            }
        }
        System.out.println("结束获取FrameGrabber grabber："+grabber);
        OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
        System.out.println("开始获取OpenCVFrameConverter.ToIplImage："+converter);

        Frame grabframe =grabber.grab();
        IplImage grabbedImage =null;
        if(grabframe!=null){
            System.out.println("取到第一帧");
            grabbedImage = converter.convert(grabframe);
        }else{
            System.out.println("没有取到第一帧");
        }
        System.out.println("结束获取converter："+converter);
        opencv_imgcodecs.cvSaveImage("D:\\FFOutput\\hello.jpg", grabbedImage);//来保存图片

        FrameRecorder recorder;
        try {
            recorder = FrameRecorder.createDefault(outputFile, width, height);

        } catch (org.bytedeco.javacv.FrameRecorder.Exception e) {
            throw e;
        }

        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); // avcodec.AV_CODEC_ID_H264
        recorder.setFormat("flv");
        recorder.setFrameRate(v_rs);
        recorder.setGopSize(v_rs);

        System.out.println("准备开始推流...");
        try {
//            recorder.setInterleaved(true);
//            // 降低编码延时
//            recorder.setVideoOption("tune", "zerolatency");
//            // 提升编码速度
//            recorder.setVideoOption("preset", "ultrafast");
//            // 视频质量参数(详见 https://trac.ffmpeg.org/wiki/Encode/H.264)
//            recorder.setVideoOption("crf", "28");
//            // 分辨率
            recorder.setVideoBitrate(rate);
            recorder.setFrameRate(fps);
//            // 视频编码格式
//            recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
//            // 视频格式
//            recorder.setFormat("flv");
//            // 视频帧率
//            recorder.setGopSize(60);
//            recorder.setAudioOption("crf", "0");
//            recorder.setAudioQuality(0);
            recorder.setAudioBitrate(audioRate);
            recorder.setSampleRate(44100);
//            // 建议从grabber获取AudioChannels
//            recorder.setAudioChannels(1);
//            recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
            recorder.start();
        } catch (org.bytedeco.javacv.FrameRecorder.Exception e) {
            try {
                System.out.println("录制器启动失败，正在重新启动...");
                if(recorder!=null)
                {
                    System.out.println("尝试关闭录制器");
                    recorder.stop();
                    System.out.println("尝试重新开启录制器");
                    recorder.start();
                }

            } catch (org.bytedeco.javacv.FrameRecorder.Exception e1) {
                throw e;
            }
        }

        System.out.println("开始推流");

        while ((grabframe=grabber.grab()) != null) {
            // frame.showImage(grabframe);

            grabbedImage = converter.convert(grabframe);
            Frame rotatedFrame = converter.convert(grabbedImage);

            if (startTime == 0) {
                startTime = System.currentTimeMillis();
            }
            recorder.setTimestamp(1000 * (System.currentTimeMillis() - startTime));

            if(rotatedFrame!=null &&  rotatedFrame.imageHeight > 0 && rotatedFrame.imageWidth > 0){
                recorder.record(rotatedFrame);
            }

        }
        recorder.stop();
        recorder.release();
        grabber.stop();
        System.exit(2);
    }
    

}